Skip to content
This repository has been archived by the owner on Feb 18, 2024. It is now read-only.

allow passing default values to environment plugin #657

Closed
wants to merge 1 commit into from

Conversation

zeropaper
Copy link
Contributor

.use(EnvironmentPlugin, ['NODE_ENV', ...envs]);
.use(EnvironmentPlugin, Array.isArray(envs) ?
['NODE_ENV', ...envs] :
[{ NODE_ENV: 'development', ...envs }]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the envs value is an array, we should be spreading into the array instead of the object:

[{ NODE_ENV: 'development' }, ...envs]);

Copy link
Member

@eliperelman eliperelman Jan 8, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, we should probably be using the value from neutrino.options.env.NODE_ENV.

[{ NODE_ENV: neutrino.options.env.NODE_ENV }, ...envs]);

Thoughts? cc: @SeeThruHead

Copy link
Contributor Author

@zeropaper zeropaper Jan 13, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the late reply, crazy week.
Not sure about spreading into the array

[{ NODE_ENV: 'development' }, ...envs])

because according to the Webpack docs, it can be an array OR an object (which then holds the default values).
There's also a syntax problem with older node versions which don't allow spreading object anyways.
I will make the neutrino.options.env.NODE_ENV.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Older Node doesn't allow spreading into objects, but does allow arrays, at least for the Node versions that Neutrino supports.

Doesn't an array of objects support both, by allowing multiple values with defaults?

[
  // Pulls in NODE_ENV with the value defaulted to neutrino.options.env.NODE_ENV
  { NODE_ENV: neutrino.options.env.NODE_ENV },
  // Brings in any other envs, whether they are strings or objects
  ...envs
];

@eliperelman
Copy link
Member

Looks like we had a merge in master here instead of a rebase, so it's showing a lot more commits. Could you fix that? Thanks!

@eliperelman
Copy link
Member

I had another read of https://webpack.js.org/plugins/environment-plugin/. It either takes an array of string keys, or an object mapping the keys to the default values.

Unfortunately the else clause will violate that. I think the correct course of action to take would be to switch this middleware to always take an object; the bad news: that's a breaking change.

Right now the only thing we can do is leave the plugin as is, and allow consumers to override it if they want to replace the arg. We will have to wait on this PR until we are ready for Neutrino v9. Then we can switch to

module.exports = (neutrino, opts = {}) => {
  neutrino.config
    .plugin('env')
      .use(EnvironmentPlugin, merge({
        NODE_ENV: 'development'
      }, opts);
};

Unfortunately right now we can't move forward. 😢

@zeropaper
Copy link
Contributor Author

zeropaper commented Jan 16, 2018 via email

@eliperelman
Copy link
Member

@zeropaper with master now representing what will be released in v9, would you be willing to pick this up again?

@ftes
Copy link

ftes commented May 24, 2018

Shouldn't this line be backwards compatible and allow passing an object?

 .use(EnvironmentPlugin, Array.isArray(envs) ? ['NODE_ENV', ...envs] : { 'NODE_ENV': 'development', ...envs });

(see #749)

@zeropaper
Copy link
Contributor Author

zeropaper commented May 24, 2018

@ftes i think it should be backward compatible (and my PR reflects it: 4f6b4bf).
Time as passed and I don't have the whole issue in mind anymore but will look at it in the next days (unless you want to take care of it ASAP)

pluginOptions = ['NODE_ENV', ...envs];
}
else {
pluginOptions = [
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ftes i think it should be backward compatible (and my PR reflects it: 4f6b4bf).

Your PR is slightly different because it wraps the object inside an array.

I think this is what @eliperelman meant with

Unfortunately the else clause will violate that.

@ftes
Copy link

ftes commented May 24, 2018

unless you want to take care of it ASAP

Not urgent for me, happy to wait. Let me know if I can be of any more help.

@zeropaper
Copy link
Contributor Author

zeropaper commented May 25, 2018

I actually dug a bit and apparently, the use() method is expecting an array:

use(plugin, args = []) {
    return this
      .set('plugin', plugin)
      .set('args', args);
}

the instanciation of the plugin is done in webpack-chain/Plugin.js (line 9)

this.init((Plugin, args = []) => new Plugin(...args)); // it hardly would make sense to me for "args" to be an object

so, unless I miss something.. this PR should be merged as-is.

@edmorley
Copy link
Member

edmorley commented Jul 5, 2018

So there are a few things here that I think made this issue confusing:

  • webpack-chain's config.plugin('foo').use(SomePlugin, args) actually expects args to be an array of arguments, that will then be expanded. So if one wants to pass an array as the first argument, the correct form is .use(SomePlugin, [ ['var'] ]), which then internally results in new SomePlugin(['var']).
  • Even though the EnvironmentPlugin docs don't mention it, there is actually a third way to pass the environment variable keys: as separate arguments (rather than an array). ie: new EnvironmentPlugin('var', 'another_var').

As such, the current @neutrinojs/env implemention's .use(EnvironmentPlugin, envs) (and the same prior to the webpack 4 changes) is actually using this hidden third form instead of the array form - ie: new EnvironmentPlugin(...envs) rather than new EnvironmentPlugin(envs).

Now that NODE_ENV is no longer set (as of #809), it's much simpler to support both the array and object forms. I also think @neutrinojs/env should be removed and just inlined in @neutrinojs/web.

I'll open a PR for this now, since removing @neutrinojs/env (and any other packages) blocks releasing the first alpha (since we don't want to issue a v9 alpha of any package that won't have a final version release).

@edmorley edmorley closed this in #983 Jul 9, 2018
edmorley added a commit that referenced this pull request Jul 9, 2018
Since `EnvironmentPlugin` doesn't require any non-webpack dependencies
or complex configuration, it's simpler to inline the plugin directly
in presets that use it (which is currently just the web preset).

The argument passed to the plugin is now correctly wrapped in an array
(as expected by `webpack-chain`), meaning the object form that allows
setting defaults is now also supported:
https://webpack.js.org/plugins/environment-plugin/#usage-with-default-values

Closes #657.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Development

Successfully merging this pull request may close these issues.

4 participants